#include "cv_ssd.h"
#include <QDebug>
#include <iostream>

using namespace std;

String labelFile = "ssd/labelmap_det.txt";
String modelFile = "debug/ssd/MobileNetSSD_deploy.caffemodel";
String model_text_file = "debug/ssd/MobileNetSSD_deploy.prototxt";

String objNames[] = {
    "background",
    "aeroplane",
    "bicycle",
    "bird",
    "boat",
    "bottle",
    "bus",
    "car",
    "cat",
    "chair",
    "cow",
    "diningtable",
    "dog",
    "horse",
    "motorbike",
    "person",
    "pottedplant",
    "sheep",
    "sofa",
    "train",
    "tvmonitor"
};

cv::Mat * ssd_detect(cv::Mat *inframe,std::string modelFile,std::string model_text_file) {
    if (inframe->empty() || (modelFile == "") || (model_text_file == "")) {
        printf("could not load image...\n");
        return inframe;
    }
    cv::Mat  resize;
    cv::resize(*inframe, resize,
        Size(480,560),
        0, 0, INTER_LINEAR);// X Y各缩小一半
    cv::Mat *image2 = new cv::Mat(480,640,CV_8UC3);
    cv::cvtColor(resize,*image2,COLOR_RGBA2RGB);
    Mat blobImage1 = blobFromImage(*image2, 0.007843,
        Size(300, 300),
        Scalar(127.5, 127.5, 127.5), true, false);


////    image：这个就是我们将要输入神经网络进行处理或者分类的图片。
////    mean：需要将图片整体减去的平均值，如果我们需要对RGB图片的三个通道分别减去不同的值，那么可以使用3组平均值，
////    如果只使用一组，那么就默认对三个通道减去一样的值。减去平均值（mean）：为了消除同一场景下不同光照的图片，
////     对我们最终的分类或者神经网络的影响，我们常常对图片的R、G、B通道的像素求一个平均值，
////   然后将每个像素值减去我们的平均值，这样就可以得到像素之间的相对值，就可以排除光照的影响。
////    scalefactor：当我们将图片减去平均值之后，还可以对剩下的像素值进行一定的尺度缩放，
////    它的默认值是1，如果希望减去平均像素之后的值，全部缩小一半，那么可以将scalefactor设为1/2。
////    size：这个参数是我们神经网络在训练的时候要求输入的图片尺寸。
////    swapRB：OpenCV中认为我们的图片通道顺序是BGR，但是我平均值假设的顺序是RGB，
/// 所以如果需要交换R和G，那么就要使swapRB=true
///
    Net net = readNetFromCaffe(model_text_file, modelFile);
    net.setInput(blobImage1, "data");
    Mat detection = net.forward("detection_out");
    Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr<float>());
    float confidence_threshold = 0.2;
    for (int i = 0; i < detectionMat.rows; i++) {
        float confidence = detectionMat.at<float>(i, 2);
        if (confidence > confidence_threshold) {
            size_t objIndex = (size_t)(detectionMat.at<float>(i, 1));
            float tl_x = detectionMat.at<float>(i, 3) * image2->cols;
            float tl_y = detectionMat.at<float>(i, 4) * image2->rows;
            float br_x = detectionMat.at<float>(i, 5) * image2->cols;
            float br_y = detectionMat.at<float>(i, 6) * image2->rows;

            Rect object_box((int)tl_x, (int)tl_y, (int)(br_x - tl_x), (int)(br_y - tl_y));
            rectangle(*image2, object_box, Scalar(0, 0, 255), 2, 8, 0);
            putText(*image2, format("%s", objNames[objIndex].c_str()),
                    Point(tl_x, tl_y), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(255, 0, 0), 2);
        }
    }
    return image2;
}


